#target illustrator

var gPdfOpenOptionsSupported = false;

/**
 * Batch process PDF files to clean artwork, resize artboard, and scale contents.
 * Compatible with Adobe Illustrator 2025.
 */
(function () {
    if (app.name !== "Adobe Illustrator") {
        alert("请在 Adobe Illustrator 中运行此脚本。");
        return;
    }

    gPdfOpenOptionsSupported = isPdfOpenOptionsSupported();
    if (!gPdfOpenOptionsSupported) {
        alert("注意：当前 Illustrator 版本无法使用 PDF 打开选项，脚本将采用默认设置打开 PDF。");
    }

    var originalInteractionLevel = app.userInteractionLevel;
    var originalCoordinateSystem = app.coordinateSystem;

    app.userInteractionLevel = UserInteractionLevel.DONTDISPLAYALERTS;
    app.coordinateSystem = CoordinateSystem.ARTBOARDCOORDINATESYSTEM;

    try {
        run();
    } catch (error) {
        alert("脚本执行失败: " + error.message);
    } finally {
        app.userInteractionLevel = originalInteractionLevel;
        app.coordinateSystem = originalCoordinateSystem;
    }
})();

function run() {
    var widthInput = promptForPositiveNumber("请输入目标画板宽度（毫米）:", "300");
    if (widthInput === null) {
        return;
    }

    var scaleInput = promptForPositiveNumber("请输入最终缩放百分比（例如 100）:", "100");
    if (scaleInput === null) {
        return;
    }

    var inputFolder = Folder.selectDialog("请选择 PDF 输入文件夹");
    if (!inputFolder) {
        return;
    }

    var outputFolder = Folder.selectDialog("请选择输出文件夹");
    if (!outputFolder) {
        return;
    }

    var pdfFiles = inputFolder.getFiles(function (item) {
        return item instanceof File && /\.pdf$/i.test(item.name);
    });

    if (pdfFiles.length === 0) {
        alert("选定的输入文件夹中没有 PDF 文件。");
        return;
    }

    var targetWidthPt = mmToPoint(widthInput);
    var finalScaleFactor = scaleInput / 100;
    var processed = 0;
    var failures = [];

    for (var i = 0; i < pdfFiles.length; i++) {
        var pdfFile = pdfFiles[i];
        try {
            processPdfFile(pdfFile, outputFolder, targetWidthPt, finalScaleFactor);
            processed++;
        } catch (fileError) {
            failures.push(pdfFile.displayName + ": " + fileError.message);
        }
    }

    showSummary(processed, pdfFiles.length, failures);
}

function processPdfFile(pdfFile, outputFolder, targetWidthPt, finalScaleFactor) {
    var openOptions = createPdfOpenOptions();
    var document = openOptions ? app.open(pdfFile, openOptions) : app.open(pdfFile);

    try {
        unlockAndReveal(document);
        cleanDocument(document);
        removeArtworkOutsideActiveArtboard(document);

        var artboardIndex = document.artboards.getActiveArtboardIndex();
        var hasArtwork = selectActiveArtboardItems(document);

        if (hasArtwork) {
            document.fitArtboardToSelectedArt(artboardIndex);
            app.selection = null;
            if (selectActiveArtboardItems(document)) {
                var artboard = document.artboards[artboardIndex];
                var artboardRect = artboard.artboardRect.slice(0);
                var originalWidth = artboardRect[2] - artboardRect[0];
                var selectedItems = getSelectionArray();

                if (selectedItems.length > 0 && Math.abs(originalWidth) > 0.001) {
                    var scaleToTarget = targetWidthPt / originalWidth;

                    scaleArtboard(artboard, artboardRect, targetWidthPt);
                    var artboardCenter = getRectCenter(artboard.artboardRect);
                    scaleItemsAroundPoint(selectedItems, artboardCenter, scaleToTarget);

                    if (finalScaleFactor !== 1) {
                        artboardCenter = getRectCenter(artboard.artboardRect);
                        scaleItemsAroundPoint(selectedItems, artboardCenter, finalScaleFactor);
                    }
                }
            }
        }

        app.selection = null;
        saveAsPdf(document, outputFolder, pdfFile.displayName);
    } finally {
        document.close(SaveOptions.DONOTSAVECHANGES);
    }
}

function unlockAndReveal(document) {
    app.selection = null;
    try {
        document.selection = null;
    } catch (_) {}

    try {
        app.executeMenuCommand("unlockAll");
    } catch (_) {}
    try {
        app.executeMenuCommand("showAll");
    } catch (_) {}
}

function cleanDocument(document) {
    removeEmptyPathItems(document);
    removeStrayPathItems(document);
    removeEmptyTextFrames(document);
}

function removeArtworkOutsideActiveArtboard(document) {
    app.selection = null;
    try {
        document.selectObjectsOnActiveArtboard();
    } catch (_) {
        app.selection = null;
        return;
    }

    var hasInsideSelection = app.selection && app.selection.length > 0;
    if (!hasInsideSelection) {
        app.selection = null;
        return;
    }

    var inverseDone = inverseSelection();
    if (inverseDone && app.selection && app.selection.length > 0) {
        if (!clearSelection()) {
            removeItemsFromSelection(app.selection);
        }
    } else if (app.selection && app.selection.length > 0) {
        removeItemsFromSelection(app.selection);
    }

    app.selection = null;
}

function removeEmptyPathItems(document) {
    var items = document.pathItems;
    for (var i = items.length - 1; i >= 0; i--) {
        var item = items[i];
        if (!item || item.locked || item.guides || item.clipping) {
            continue;
        }
        if (!item.filled && !item.stroked) {
            item.remove();
            continue;
        }
        if (item.closed) {
            try {
                if (Math.abs(item.area) < 0.01) {
                    item.remove();
                    continue;
                }
            } catch (_) {}
        }
    }
}

function removeStrayPathItems(document) {
    var items = document.pathItems;
    for (var i = items.length - 1; i >= 0; i--) {
        var item = items[i];
        if (!item || item.locked || item.guides || item.clipping) {
            continue;
        }
        if (item.pathPoints && item.pathPoints.length <= 1) {
            item.remove();
        }
    }
}

function removeEmptyTextFrames(document) {
    var frames = document.textFrames;
    for (var i = frames.length - 1; i >= 0; i--) {
        var frame = frames[i];
        if (!frame || frame.locked) {
            continue;
        }
        if (frame.characters.length === 0) {
            frame.remove();
        }
    }
}

function selectActiveArtboardItems(document) {
    app.selection = null;
    try {
        document.selectObjectsOnActiveArtboard();
    } catch (error) {
        throw new Error("无法选择画板内容: " + error.message);
    }
    return app.selection && app.selection.length > 0;
}

function getSelectionArray() {
    var selection = app.selection || [];
    var result = [];
    for (var i = 0; i < selection.length; i++) {
        result.push(selection[i]);
    }
    return result;
}

function scaleArtboard(artboard, currentRect, targetWidthPt) {
    var currentWidth = currentRect[2] - currentRect[0];
    if (Math.abs(currentWidth) < 0.001) {
        throw new Error("画板宽度为零，无法缩放。");
    }

    var currentHeight = currentRect[1] - currentRect[3];
    var scaleFactor = targetWidthPt / currentWidth;
    var newHeight = currentHeight * scaleFactor;
    var center = getRectCenter(currentRect);

    artboard.artboardRect = [
        center[0] - targetWidthPt / 2,
        center[1] + newHeight / 2,
        center[0] + targetWidthPt / 2,
        center[1] - newHeight / 2
    ];
}

function scaleItemsAroundPoint(items, anchor, scaleFactor) {
    if (Math.abs(scaleFactor - 1) < 0.0001) {
        return;
    }

    var scalePercent = scaleFactor * 100;
    for (var i = 0; i < items.length; i++) {
        var item = items[i];
        if (!item || item.locked) {
            continue;
        }

        var beforeBounds = item.geometricBounds;
        var beforeCenter = getRectCenter(beforeBounds);

        try {
            item.resize(
                scalePercent,
                scalePercent,
                true,
                true,
                true,
                true,
                true,
                Transformation.CENTER
            );
        } catch (_) {
            continue;
        }

        var afterBounds = item.geometricBounds;
        var afterCenter = getRectCenter(afterBounds);

        var targetCenterX = anchor[0] + (beforeCenter[0] - anchor[0]) * scaleFactor;
        var targetCenterY = anchor[1] + (beforeCenter[1] - anchor[1]) * scaleFactor;
        var deltaX = targetCenterX - afterCenter[0];
        var deltaY = targetCenterY - afterCenter[1];

        try {
            item.translate(deltaX, deltaY);
        } catch (_) {}
    }
}

function saveAsPdf(document, outputFolder, fileName) {
    var outputFile = new File(outputFolder.fsName + "/" + fileName);
    var pdfOptions = new PDFSaveOptions();
    pdfOptions.preserveEditability = true;
    document.saveAs(outputFile, pdfOptions);
}

function showSummary(processed, total, failures) {
    var message = "已处理 PDF 数量: " + processed + "/" + total;
    if (failures.length > 0) {
        message += "\n以下文件处理失败：\n" + failures.join("\n");
    }
    alert(message);
}

function promptForPositiveNumber(promptText, defaultValue) {
    var response = prompt(promptText, defaultValue);
    if (response === null) {
        return null;
    }

    var value = Number(response);
    if (isNaN(value) || value <= 0) {
        alert("请输入大于零的有效数字。");
        return promptForPositiveNumber(promptText, defaultValue);
    }

    return value;
}

function inverseSelection() {
    var commands = ["Inverse", "Inverse menu item", "ai_inverse"];
    for (var i = 0; i < commands.length; i++) {
        try {
            app.executeMenuCommand(commands[i]);
            return true;
        } catch (_) {}
    }
    return false;
}

function clearSelection() {
    var commands = ["clear", "Delete", "cut"];
    for (var i = 0; i < commands.length; i++) {
        try {
            app.executeMenuCommand(commands[i]);
            return true;
        } catch (_) {}
    }
    return false;
}

function removeItemsFromSelection(selection) {
    if (!selection || selection.length === 0) {
        return;
    }

    var items = [];
    for (var i = 0; i < selection.length; i++) {
        var item = selection[i];
        if (!item || item.locked) {
            continue;
        }
        items.push(item);
    }

    for (var j = 0; j < items.length; j++) {
        try {
            items[j].remove();
        } catch (_) {}
    }
}

function createPdfOpenOptions() {
    if (!gPdfOpenOptionsSupported || typeof PDFOpenOptions === "undefined") {
        return null;
    }

    try {
        var options = new PDFOpenOptions();
        options.preserveEditability = true;
        return options;
    } catch (_) {
        gPdfOpenOptionsSupported = false;
        return null;
    }
}

function isPdfOpenOptionsSupported() {
    if (typeof PDFOpenOptions === "undefined") {
        return false;
    }

    try {
        var temp = new PDFOpenOptions();
        return !!temp;
    } catch (_) {
        return false;
    }
}

function mmToPoint(mm) {
    return mm * 72 / 25.4;
}

function getRectCenter(rect) {
    return [
        (rect[0] + rect[2]) / 2,
        (rect[1] + rect[3]) / 2
    ];
}
